module REG_ID_EX(
    input clk,
    input rst_n,
    input flush,
    input forward_rD1,
    input forward_rD2,
    input rf_we_in,
    input dram_we_in,
    input asel_in,
    input wb_pc_sel_in,
    input debug_have_inst_in,
    input [2:0] wd_sel_in,
    input [1:0] jump_in,
    input [2:0] branch_in,
    input [3:0] alu_op_in,
    input [4:0] wR_in,
    input [31:0] pcimm_in,
    input [31:0] rD1_in,
    input [31:0] rD2_in,
    input [31:0] imm_in,
    input [31:0] pc4_in,
    input [31:0] rD1_f, 
    input [31:0] rD2_f, 
    input [31:0] pc_in,

    input [3:0] load_sel_in,
    input [2:0] store_sel_in,
    output reg [3:0] load_sel_out,
    output reg [2:0] store_sel_out,

    output reg rf_we_out,
    output reg dram_we_out,
    output reg asel_out,
    output reg wb_pc_sel_out,
    output reg debug_have_inst_out,
    output reg [1:0] jump_out,
    output reg [2:0] wd_sel_out,
    output reg [2:0] branch_out,
    output reg [3:0] alu_op_out,
    output reg [4:0] wR_out,
    output reg [31:0] pc4_out,
    output reg [31:0] rD1_out,
    output reg [31:0] rD2_out,
    output reg [31:0] imm_out,
    output reg [31:0] pcimm_out,
    output reg [31:0] pc_out
    );
    
    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n)      pc_out <= 32'b0;
        else if(flush)  pc_out <= 32'b0;
        else            pc_out <= pc_in;
    end
    
    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n)      debug_have_inst_out <= 1'b0;
        else if(flush)  debug_have_inst_out <= 1'b0;
        else            debug_have_inst_out <= debug_have_inst_in;
    end
    
    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n)      wd_sel_out <= 2'b0;
        else            wd_sel_out <= wd_sel_in;
    end

    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n)      wb_pc_sel_out <= 1'b0;
        else            wb_pc_sel_out <= wb_pc_sel_in;
    end
    
    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n)      load_sel_out <=  3'b0;
        else            load_sel_out <= load_sel_in;
    end

    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n)      store_sel_out <=  2'b0;
        else            store_sel_out <= store_sel_in;
    end

    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n)      alu_op_out <= 4'b0;
        else            alu_op_out <= alu_op_in;
    end
    
    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n)      asel_out <= 1'b0;
        else            asel_out <= asel_in;
    end
    
    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n)      rf_we_out <= 1'b0;
        else if(flush)  rf_we_out <= 1'b0;
        else            rf_we_out <= rf_we_in;
    end
    
    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n)      dram_we_out <= 1'b0;
        else if(flush)  dram_we_out <= 1'b0;
        else            dram_we_out <= dram_we_in;
    end
    
    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n)      branch_out <= 3'b010;
        else if(flush)  branch_out <= 3'b010;       // is_not_B
        else            branch_out <= branch_in;
    end
    
    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n)      jump_out <= 2'b0;
        else if(flush)  jump_out <= 2'b0;
        else            jump_out <= jump_in;
    end
    
    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n)      pcimm_out <= 32'b0;
        else            pcimm_out <= pcimm_in;
    end
    
    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n)      rD1_out <= 32'b0;
        else if(forward_rD1) rD1_out <= rD1_f;
        else            rD1_out <= rD1_in;
    end
    
    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n)           rD2_out <= 32'b0;
        else if(forward_rD2) rD2_out <= rD2_f;
        else                 rD2_out <= rD2_in;
    end
    
    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n)      imm_out <= 32'b0;
        else            imm_out <= imm_in;
    end

    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n)      pc4_out <= 32'b0;
        else            pc4_out <= pc4_in;
    end

    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n)      wR_out <= 5'b0;
        else            wR_out <= wR_in;
    end

endmodule
